<?php
defined('BASEPATH') or exit('No direct script access allowed');

class Curl extends MY_Controller {

	// 定义识别code的属性
	public $pattern1 = '/PRE|399\d{3}|09[01]\d{3}|10[3-7]\d{3}/';
	public $pattern2 = '/PRE|B|ST|沪|全指|上证|指数|等权|中证|50|100|180|200|300|380|400|600|800|细分|主题|消费|优势|民企|国企|红利|全R成长|市值百强|内地|大盘|新能源|总成交|债券|创业板|两岸三地|领先行业|非周期|CSSW丝路|ESG40|分离债|沪财中小|兴证海峡|医药生物|A股资源|持续产业|5年信用|高端装备|创业成长|银河99/';

	// 定义了一个方法，方法的名称为index
	public function index() {
		$this->loadview('selector.html');
	}

	// 显示清空数据表视图
	public function displayClearTool() {
		$this->loadview('displayClearTool.php');
	}

	/**
	 * 清空数据表
	 */
	public function clearStock() {
		$this->Stocks->resetStocksTable();
	}

	/**
	 * 生成抓取股票名称数据的页面
	 */
	public function displayMultiStocks($step = 10) {
		$this->output->enable_profiler(TRUE);

		// 初始化数组
		$stepData['step'][0] = 0;
		// 获取全部页面的数量
		$totalPages = ceil($this->Curlmodel->GetTotalPages() / 90);
		// 生成步长数组
		for ($i = 0; $i <= $totalPages; $i = $i + $step) {
			$next = ($i + $step <= $totalPages) ? ($i + $step) : $totalPages;
			array_push($stepData['step'], $next);
		}
		$this->loadview('getAllStockName', $stepData);
	}

	public function getAllStockName() {
		// 取消页面执行时间的限制
		set_time_limit(0);
		// 获取指定页面存储在本地的cookie信息
		$cookie_file = $this->Curlmodel - getCookieByHttps('https://xueqiu.com/hq#exchange=CN&firstName=1&secondName=1_0');
		// 获取全部页面的数量
		$totalPages = ceil($this->Curlmodel->GetTotalPages() / 90);
		// 获取行情中心的股票信息
		for ($i = 1; $i <= $totalPages; $i++) {
			$url = 'http://xueqiu.com/stock/cata/stocklist.json?page=' . $i . '&size=90&order=desc&orderby=percent&type=11%2C12&_=1447474625890';
			// 后面类似时间戳的字符串需要更新
			// http://xueqiu.com/stock/cata/stocklist.json?page=1&size=30&order=desc&orderby=percent&type=11%2C12&_=1447474625890
			$this->getFromXueqiu($url, $cookie_file);
		}
		// 调用自定义函数显示信息，并跳转
		message('Curl/index', '抓取成功，接下来应该清理数据了。');
	}

	/**
	 * [getFromXueqiu 从雪球抓取指定指定页面中的代码信息]
	 * @param  string $url [description]
	 * @param  string $cookie_file [description]
	 * @return [type]              [description]
	 */
	public function getFromXueqiu($url = '', $cookie_file = '') {
		$string = $this->Curlmodel->curl_https($url, $cookie_file);
		$array = json_decode($string, true);
		foreach ($array['stocks'] as $value) {
			$data = array(
				'symbol' => $value['symbol'],
				'scode' => $value['code'],
				'sname' => $value['name'],
			);
			$this->Stocks->replaceStockName($data);
			// 使用replace一个语句可以完成上面两个语句的功能,其语法与insert差不多.
			// 如上面的操作可以写为replace into test set id=1,value='a',icount=0;
			// 则表中有id为1时,先删除旧数据.然后插入新数据.否则直接插入数据.
		}
	}

	/**
	 * 抓取指定页面的公司名称信息，并且将进度信息写入对应的文件中
	 */
	public function getMultiStockName($start, $end) {
		// 取消页面执行时间的限制
		set_time_limit(0);
		// 重置进度内容
		$fileName = './application/tmp/stockpage' . $start . $end . '.txt';
		file_put_contents($fileName, ''); //写入缓存
		// 获取指定页面存储在本地的cookie信息
		$cookie_file = $this->Curlmodel->getCookieByHttps('https://xueqiu.com/hq#exchange=CN&firstName=1&secondName=1_0');
		// $current_workflow_file = tempnam(sys_get_temp_dir(), "workflow");
		// var_dump($current_workflow_file);
		// if ($end == ceil($this->Curlmodel->GetTotalPages() / 90)) {
		// 	$end++;
		// }
		//以确保到达output_buffering值。
		// print str_repeat(" ", 4096);
		// ob_start();

		// 获取行情中心的股票信息
		for ($i = $start + 1; $i <= $end; $i++) {
			$url = 'https://xueqiu.com/stock/cata/stocklist.json?page=' . $i . '&size=90&order=desc&orderby=percent&type=11%2C12&_=1447474625890';
			// 后面类似时间戳的字符串需要更新
			$this->getFromXueqiu($url, $cookie_file);
			// 计算进度
			// $workInfo = array('percent' => round($i / $end * 100, 0));
			$workInfo = round(($i - $start) / ($end - $start) * 100, 0);
			// 存储到数据库
			// $this->Curlmodel->saveProgressingInfo('010sn', $workInfo);
			//          $GLOBALS['workInfo'] = something;
			// $_SESSION['pace'] = $workInfo;
			// // $workInfo = array('percent' => 20);
			// // 拼接文件名称
			// // 打开文件，覆盖写入
			// fopen($fileName, 'w+');
			// // 写入进度数组
			file_put_contents($fileName, $workInfo); //写入缓存
			// // sleep(2);
			// // echo '<p>抓取' . $i . '页成功！</p>';
			// ob_flush();
			// flush();
			// ob_end_flush();
			// sleep(20);
		}
		// $handle = fopen($current_workflow_file, 'r');
		// $cacheArray = unserialize(fread($handle, filesize($current_workflow_file)));
		// var_dump($cacheArray);
		$this->output->enable_profiler(TRUE);

	}

	// 显示抓取公司股票代码进度页面
	public function displayStockProgress($start, $end) {
		$data['start'] = $start;
		$data['end'] = $end;
		$this->loadview('gettingStockProgress', $data);
	}

	/**
	 * 设置非上市公司代码标记
	 */
	public function setStocksFlag() {
		// 取消页面执行时间的限制
		set_time_limit(0);

		// 重设进度信息
		$fileName = './application/tmp/checkflag.txt';
		file_put_contents($fileName, ''); //写入缓存

		// 逐一读取数据库中的代码信息后，与特征标记进行对比，对非上市公司进行标记
		// $this->displayProgressBar();
		$total = $this->Stocks->getTotalNumber();
		for ($i = 1; $i <= $total; $i++) {
			// 第一步，读取指定编号的数据库信息
			$info = $this->Stocks->getByID($i);
			// 第二步，使用正则表达式进行筛选
			if (preg_match($this->pattern1, $info[0]['scode']) || preg_match($this->pattern2, $info[0]['sname'])) {
				$this->Stocks->setFlagBySymbol($info[0]['symbol'], 0);
			}
			// 将进度信息写入对应文件
			file_put_contents($fileName, round($i / $total * 100, 0)); //写入缓存
		}
		// message('Curl/index', '标记成功，接下来应该抓取财务信息了。');
	}

	/**
	 * 显示设置公司标记进度页面
	 */
	public function displayCheckingProgress() {
		$this->loadview('checkingProgress');
	}

	// 设定指定代码的标记
	public function setFlag($symbol) {
		$this->Stocks->setFlagBySymbol($symbol, 0);
		message('analytics/displayGrowthing', '标记成功!');
	}

	/**
	 * 生成多个抓取财务数据的页面
	 */
	public function multithreading($step = 200) {
		// 初始化数组
		$stepData['step'][0] = 0;
		// 取得全部合格代码
		$data = $this->Stocks->getTotalcode();
		// 生成步长数组
		for ($i = 0; $i <= count($data); $i = $i + $step) {
			$next = ($i + $step <= count($data)) ? ($i + $step) : count($data);
			array_push($stepData['step'], $next);
		}
		$this->loadview('getAllStockInfo', $stepData);
	}

	// 显示单个抓取财务信息进度页面
	public function curlFinaceProgress($start = 0, $end = 0) {
		$data['start'] = $start;
		$data['end'] = $end;
		$this->loadview('gettingCropProgress', $data);
	}

	/**
	 * 抓取并存储指定公司的财务数据
	 */
	public function getFinanceInfoByCode($code = '300461') {
		// $this->output->enable_profiler(TRUE);
		// 第一步，抓取主要财务数据、现金流量表
		$url1 = 'http://stockpage.10jqka.com.cn/basic/' . $code . '/main.txt';
		$main = $this->Curlmodel->curl($url1);
		if (empty($main)) {
			// 设置标记为0
			$this->Stocks->setFlag($code, false);
			echo $code . '没有数据<br />';
		} else {
			// 第二步，将json格式转为数组
			$main = $this->Curlmodel->json2array($main);
			$url2 = 'http://stockpage.10jqka.com.cn/basic/' . $code . '/cash.txt';
			$cash = $this->Curlmodel->curl($url2);
			// 第二步，将json格式转为数组
			$cash = $this->Curlmodel->json2array($cash);
			// var_dump($cash);exit;
			// var_dump($data['report']);
			// 第三步，将必要的数据插入到数据库
			// 必要的数据有：年度、基本每股收益(元)、净利润、净利润同比增长率、净资产收益率、营业总收入(万元)、营业总收入同比增长率(%)、每股净资产(元)、经营现金流量净额(万元)、投资现金流量净额(万元)、筹资现金流量净额(万元)
			// 3.1创建数据表
			$this->Symbol->creatFinanceTableById($code);
			// // 从同花顺提供的数组中准备必要数据，然后插入必要数据
			// 第一步，先计算总有多少季数据
			$total = sizeof($main['report'][0]);
			// 整理数据，使之适合插入到数据表
			$title = $this->Curlmodel->transform2string($main['title']);
			// 第二步，循环更新每一季财报数据
			for ($i = 0; $i < $total; $i++) {
				// 取得财务报表主要数据
				$mainData = array(
					'cwbbrq' => $main['report'][0][$i],
					'jbmgsy' => $this->Curlmodel->white2null($main['report'][$this->Curlmodel->getFinanceArrayKey('基本每股收益',
						$title)][$i]),
					'jlr' => $this->Curlmodel->white2null($main['report'][$this->Curlmodel->getFinanceArrayKey('净利润',
						$title)][$i]),
					'jlrzzl' => $this->Curlmodel->white2null($main['report'][$this->Curlmodel->getFinanceArrayKey('净利润同比增长率',
						$title)][$i]),
					'yyzsr' => $this->Curlmodel->white2null($main['report'][$this->Curlmodel->getFinanceArrayKey('营业总收入',
						$title)][$i]),
					'yyzsrzzl' => $this->Curlmodel->white2null($main['report'][$this->Curlmodel->getFinanceArrayKey('营业总收入同比增长率',
						$title)][$i]),
					'xsmlv' => $this->Curlmodel->white2null($main['report'][$this->Curlmodel->getFinanceArrayKey('销售毛利率',
						$title)][$i]),
					'mgjzc' => $this->Curlmodel->white2null($main['report'][$this->Curlmodel->getFinanceArrayKey('每股净资产',
						$title)][$i]),
					'roe' => $this->Curlmodel->white2null($main['report'][$this->Curlmodel->getFinanceArrayKey('净资产收益率-摊薄',
						$title)][$i]),
				);
				if ($this->Curlmodel->getFinanceArrayKey('销售毛利率', $title) == 0) {
					$mainData['xsmlv'] = null;
				}
				// 取得现金流量净额数据
				$cashData = $this->Curlmodel->getCashData($mainData['cwbbrq'], $cash);
				// 合并数组
				$finance = array_merge($mainData, $cashData);
				// 插入到数据库
				$this->Symbol->insertFinanceData($finance, $code);
			}
			// 设置标记为1
			// $this->Stocks->setFlag($code, true);
			echo $code . '抓取完毕' . '<br />';
		}
	}

	/**
	 * 循环抓取公司财务数据
	 */
	public function getCropFinanceInfo($begin, $end) {
		// 取消脚本运行时间限制
		set_time_limit(0);

		// 重设进度信息
		$fileName = './application/tmp/croppage' . $begin . $end . '.txt';
		file_put_contents($fileName, ''); //写入缓存

		// 取得所有公司代码
		$data = $this->Stocks->getTotalcode();
		// var_dump($data);exit;
		for ($i = $begin; $i < $end; $i++) {
			$this->getFinanceInfoByCode($data[$i]['scode']);
			// 将进度信息写入对应文件
			file_put_contents($fileName, round(($i - $begin) / ($end - $begin) * 100, 0)); //写入缓存
		}
	}

	/**
	 * 显示检查进度视图
	 */
	public function displayCropChecking() {
		// 显示检查过程
		$this->loadview('checkCrop');
	}

	/**
	 * 检查公司财务数据抓取结果,根据雪球网的公司名称，判断是否存在相应公司表
	 * 如果没有表的话，则从同花顺网站重新抓取。
	 */
	public function checkCropTable() {
		/// 取消脚本运行时间限制
		set_time_limit(0);
		// 重设进度信息
		$fileName = './application/tmp/checkTable.txt';
		file_put_contents($fileName, ''); //写入缓存
		// 先获取全部合格公司名单
		$data = $this->Stocks->getTotalcode();
		// 循环检查是否存在对应的财务数据表
		for ($i = 0; $i < sizeof($data); $i++) {
			if (false == $this->Symbol->checkSymbolTable($data[$i]['scode'])) {
				// 如果不存在，则这是缺失表的标记
				$this->Stocks->setNoTableFlag($data[$i]['scode']);
				$this->getFinanceInfoByCode($data[$i]['scode']);
				echo $data[$i]['scode'] . '表不存在<br>';
			}
			// 将进度信息写入对应文件
			file_put_contents($fileName, round($i / sizeof($data)) * 100, 0); //写入缓存
		}
	}

	/**
	 * 检查非股票标记
	 */
	public function checkFlag() {
		// 获取全部标记为0的代码信息
		$data['flag0'] = $this->Stocks->getAllFlag0();
		// 过滤掉指数、预留、ST、B股
		$data['flag0'] = $this->Curlmodel->filterCode($data['flag0']);
		// 输出到视图
		$this->loadview('stocksCheck.html', $data);
	}

	/**
	 * 获取全部成长性公司的动态市盈率，并保存到数据库
	 */
	public function getGrowthingCorpPE() {
		// 设置程序运行时间
		set_time_limit(0);
		// 获取全部成长性公司名单
		$data = $this->Stocks->totalGrowthing(4, 0, -2);
		// 循环取得各自的市盈率数据
		for ($i = 0; $i < sizeof($data); $i++) {
			$pe = $this->getPE($data[$i]['scode']);
			// 更新到数据库
			$this->Stocks->updatePE($data[$i]['scode'], $pe);
		}
		message('Curl/index', '抓取成功');
	}

	/**
	 * 获取指定股票的动态市盈率
	 */
	public function getPE($symbol = '300061') {

		$url = 'http://stockpage.10jqka.com.cn/spService/' . $symbol . '/Header/realHeader';

		$data = $this->Curlmodel->curl($url, '');
		if (empty($data)) {
			// do something;
		} else {
			// 转换json为数组
			$data = json_decode($data, $assoc = true);
			return $data['syl'];
		}
	}

	/**
	 * 将选中的代码标记为指数
	 */
	public function markToIndex() {
		// 首先获得用户选中的数据
		$this->output->enable_profiler(true);
		echo 'test';
	}

	/**
	 * 获得自选股票的实时价格
	 */
	public function getPriceBySymbol() {
		// $this->output->enable_profiler(TRUE);
		// 获取所有自选股symbol
		$data = $this->Stocks->getSelectedStocks();
		$s = '';
		foreach ($data as $k => $v) {
			$s = $s . $v['symbol'] . ',';
		}
		$cookies = $this->cookie_file;
		$url = 'http://xueqiu.com/v4/stock/quote.json?code=' . $s;
		$main = $this->Curlmodel->curl($url, $cookies);
		echo $main;
	}

	public function getStocksInfoFromXueqiu() {
		// 获取雪球cookie信息
		$cookies = $this->Curlmodel->getCookieByHttps('https://xueqiu.com/S/SZ300059');
		// 获取自选股数据
		$data = $this->Stocks->getSelectedStocks();

		$step = 50;
		$k = intval(sizeof($data) / $step);
		$total = '';
		for ($i = 0; $i <= $k; $i++) {
			if (($i + 1) * $step > sizeof($data)) {
				$end = sizeof($data);
			} else {
				$end = ($i + 1) * $step;
			}
			$s = '';
			for ($j = $i * $step; $j < $end; $j++) {
				$s = $s . $data[$j]['symbol'] . ',';
			}

			$url = 'https://xueqiu.com/v4/stock/quote.json?code=' . $s;
			$main[$i] = $this->Curlmodel->curl_https($url, $cookies);
			$main[$i] = substr($main[$i], 1); /*去掉开头的｛*/
			$main[$i] = substr($main[$i], 0, -1); /*去掉结束的｝*/
		}

		for ($i = 0; $i <= $k; $i++) {
			if ($i != 0) {
				$main[$i] = ',' . $main[$i];
			}
			$total = $total . $main[$i];
		}

		$total = '{' . $total . '}';

		echo $total;
	}

	/**
	 * 更新公司最新的每股净资产信息
	 */
	public function repaireStocksMgjzc() {
		// 先从Stocks表中取得scode，然后据此查找scode表中的最近一次财务报表中的每股净资产，再将其插入到Stocks表中对应的地方。
		// 取得scode
		$data = $this->Stocks->getTotalcode();
		// var_dump($data);
		foreach ($data as $key => $value) {
			// var_dump($value['scode']);
			$mgjzc = $this->Symbol->getStockNetAssets($value['scode']);
			// var_dump($mgjzc['mgjzc']);
			$this->Stocks->updateMgjzcByScode($value['scode'], $mgjzc['mgjzc']);
		}
	}

	/**
	 * 显示更新净资产页面
	 */
	public function displayRepaireProgress() {
		$this->loadview('repaireProgress');
	}

}
